package com.yilian.reflection;

/**
 * Person类 - 用于演示Java反射功能
 * 
 * 这个类包含了各种访问修饰符的字段和方法，用于演示反射机制如何：
 * 1. 获取类的结构信息（字段、方法、构造器）
 * 2. 绕过访问控制访问私有成员
 * 3. 动态创建对象和调用方法
 * 4. 获取修饰符信息
 * 
 * @author 练习项目
 * @version 1.0
 */
public class Person {
    
    // ==================== 字段定义 ====================
    
    /**
     * 私有字段 - 姓名
     * 私有字段通常无法从类外部直接访问，但反射可以绕过这个限制
     */
    private String name;
    
    /**
     * 私有字段 - 年龄
     * 私有字段的访问需要通过反射的setAccessible(true)来设置
     */
    private int age;
    
    /**
     * 公共字段 - 公共字段值
     * 公共字段可以直接访问，也可以通过反射访问
     */
    public String publicField = "公共字段";
    
    // ==================== 构造器定义 ====================
    
    /**
     * 默认构造函数（无参构造器）
     * 反射可以通过Class.newInstance()调用此构造器
     */
    public Person() {
        this.name = "默认姓名";
        this.age = 0;
    }
    
    /**
     * 带参数构造函数
     * 反射可以通过Constructor.newInstance()调用此构造器
     * 
     * @param name 姓名
     * @param age 年龄
     */
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    /**
     * 私有构造函数
     * 私有构造器通常无法从外部调用，但反射可以绕过这个限制
     * 需要先调用setAccessible(true)设置可访问
     * 
     * @param name 姓名
     */
    private Person(String name) {
        this.name = name;
        this.age = 18;
    }
    
    // ==================== 公共方法 ====================
    
    /**
     * 获取姓名
     * 这是一个标准的getter方法，反射可以通过Method.invoke()调用
     * 
     * @return 姓名
     */
    public String getName() {
        return name;
    }
    
    /**
     * 设置姓名
     * 这是一个标准的setter方法，反射可以通过Method.invoke()调用
     * 
     * @param name 要设置的姓名
     */
    public void setName(String name) {
        this.name = name;
    }
    
    /**
     * 获取年龄
     * 
     * @return 年龄
     */
    public int getAge() {
        return age;
    }
    
    /**
     * 设置年龄
     * 
     * @param age 要设置的年龄
     */
    public void setAge(int age) {
        this.age = age;
    }
    
    // ==================== 私有方法 ====================
    
    /**
     * 私有方法 - 获取私有信息
     * 私有方法通常无法从外部调用，但反射可以绕过这个限制
     * 需要先调用setAccessible(true)设置可访问
     * 
     * @return 私有信息字符串
     */
    private String getPrivateInfo() {
        return "私有信息: " + name + ", " + age;
    }
    
    // ==================== 静态方法 ====================
    
    /**
     * 静态方法
     * 静态方法属于类而不是实例，反射调用时第一个参数传null
     * 
     * @return 静态信息字符串
     */
    public static String getStaticInfo() {
        return "这是一个静态方法";
    }
    
    // ==================== 重载方法 ====================
    
    /**
     * 无参数介绍方法
     * 这是重载方法的一个版本，反射需要根据参数类型来区分
     */
    public void introduce() {
        System.out.println("大家好，我是 " + name + "，今年 " + age + " 岁");
    }
    
    /**
     * 带参数介绍方法
     * 这是重载方法的另一个版本，反射需要根据参数类型来区分
     * 
     * @param greeting 问候语
     */
    public void introduce(String greeting) {
        System.out.println(greeting + "，我是 " + name + "，今年 " + age + " 岁");
    }
    
    // ==================== 重写方法 ====================
    
    /**
     * 重写toString方法
     * 这个方法来自Object类，反射可以获取到继承的方法
     * 
     * @return 对象的字符串表示
     */
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}